package org.gordonframework.site.views {
	import org.gordonframework.site.views.GView;

	import flash.text.AntiAliasType;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;	

	/**
	 * @author sampet
	 * 
	 * new GLabel({color:0xFF0099, size:20}, 300);
	 */
	public class GLabel extends GView {

		private static const textFormatProperties:Array = ["align", "blockIndent", "bold", "bullet", "color", "font", "indent", "italic", "kerning", "leading", "leftMargin", "letterSpacing", "rightMargin", "size", "tabStops", "target", "underline", "url"];

		public var textField:TextField;

		private var defaultSize:int;
		private var defaultFormat:TextFormat;

		/**
		 * @param defaulTextFormat 
		 * @param text
		 * @param wrapSize
		 */
		public function GLabel(defaulTextFormat:Object = null, wrapWidth:Number = -1) {
			textField = new TextField( );
			textField.autoSize = TextFieldAutoSize.LEFT;
			textField.antiAliasType = AntiAliasType.ADVANCED;
			textField.selectable = false;
			textField.embedFonts = true;
			textField.mouseEnabled = false;
			
			defaultFormat = textField.defaultTextFormat;			
			defaultSize = defaultFormat.size as int;
			
			if(defaulTextFormat) {
				setDefaultTextFormat( defaulTextFormat );	
			}
			
			if(wrapWidth > -1) {
				textField.wordWrap = true;
				textField.width = wrapWidth;
			}
			
			addChild( textField );	
		}

		override public function set width(value:Number):void {
			textField.width = value;
		} 

		override public function set height(value:Number):void {
			textField.height = value;
		}

		public function set text(value:String):void {
			if ( value != null ) {
				textField.text = value;
			} else {
				textField.text = "";
			}
		}

		public function get text():String {
			return textField.text;
		}

		public function set wordWrap(value:Boolean):void {
			textField.wordWrap = value;
			textField.multiline = value;
		}

		public function get wordWrap():Boolean {
			return textField.wordWrap;
		}

		public function addText(newText:String, textFormat:Object = null):void {
			if(newText && newText.length > 0) {
				var beginIndex:int = textField.length;
				textField.appendText( newText );
				textField.setTextFormat( createTextFormat( textFormat ), beginIndex, textField.length );
			}
		}

		public function setDefaultTextFormat(textFormat:Object):void {
			defaultFormat = textField.defaultTextFormat = createTextFormat( textFormat );
			if(textFormat.hasOwnProperty( "size" )) {	
				defaultSize = defaultFormat.size as int;
			}			
		}

		private function createTextFormat(format:Object):TextFormat {
			if(!format) {
				return defaultFormat;
			}
			var textFormat:TextFormat = new TextFormat( );
			for each(var property:String in textFormatProperties) {
				if(format[ property ]) {
					textFormat[property] = format[ property ];
				} else {
					textFormat[property] = defaultFormat[property];
				}
			}
			return textFormat;
		}

		public function constrainLineEnds():void {
			textField.textWidth;
			var lineEnding:RegExp = /(-|\s|\n|\t|\r)$/;
			if(wordWrap) {
				reduceSize( function():Boolean {
					for(var i:uint = 0; i < textField.numLines - 1 ; i++) {
						if(!lineEnding.test( textField.getLineText( i ) )) {
							return true;
						}
					}
					return false;
				} );
			}				
		}

		public function constrainLines(maxLines:uint):void {
			textField.textWidth;
			if(wordWrap) {
				reduceSize( function():Boolean {
					return textField.numLines > maxLines;
				} );
			}			
		}

		public function constrainWidth(maxWidth:Number):void {
			if(!wordWrap) {
				reduceSize( function():Boolean {
					return textField.width > maxWidth;
				} );
			}			
		}

		public function constrainHeight(maxHeight:Number):void {
			if(wordWrap) {
				reduceSize( function():Boolean {
					return textField.height > maxHeight;
				} );
			}
		}

		private function reduceSize(constraint:Function):void {
			var sizeFormat:TextFormat = new TextFormat( );
			while(constraint( ) && defaultSize > 1) {
				defaultSize--;
				sizeFormat.size = defaultSize;
				textField.setTextFormat( sizeFormat, 0, textField.length );
			}
		}
	}
}
